package com.hsh.erp.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hsh.erp.comparator.ProductComparator;
import com.hsh.erp.domain.common.Result;
import com.hsh.erp.domain.dto.OutboundDTO;
import com.hsh.erp.domain.dto.ProductDTO;
import com.hsh.erp.domain.entity.Product;
import com.hsh.erp.domain.file.FileParams;
import com.hsh.erp.domain.file.ProductExport;
import com.hsh.erp.domain.vo.OutboundVO;
import com.hsh.erp.domain.vo.ProductVO;
import com.hsh.erp.domain.vo.StockVO;
import com.hsh.erp.enums.FileEnum;
import com.hsh.erp.init.DataInitializer;
import com.hsh.erp.mapper.ProductMapper;
import com.hsh.erp.mapper.RepositoryMapper;
import com.hsh.erp.service.OutboundService;
import com.hsh.erp.service.ProductService;
import com.hsh.erp.service.StockService;
import com.hsh.erp.utils.DateUtils;
import com.hsh.erp.utils.MyBeanUtils;
import com.hsh.erp.utils.POIExcelUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author USER
 * @description 针对表【product】的数据库操作Service实现
 * @createDate 2024-05-30 16:21:43
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product>
        implements ProductService {
    @Resource
    private ProductMapper productMapper;
    @Resource
    private RepositoryMapper repositoryMapper;
    @Resource
    private OutboundService outboundService;
    @Resource
    private StockService stockService;
    @Resource
    private DataInitializer dataInitializer;

    /**
     * 获取所有未删除的商品
     *
     * @return
     */
    @Override
    public Result<List<ProductDTO>> getAll() {
        List<ProductDTO> productDTOList = DataInitializer.getProductDTOList();
        if (productDTOList.isEmpty()) {
            return getList(new ProductVO().setIsDelete(0));
        }
        return Result.success(productDTOList);
    }

    /**
     * 列表查询
     *
     * @param productVO
     * @return
     */
    @Override
    public Result<List<ProductDTO>> getList(ProductVO productVO) {
        productVO.selectInit();
        System.out.println(productVO);
        //获得商品信息，库存信息，仓库信息
        List<ProductDTO> productDTOList = productMapper.getProductList(productVO);

        //获得近30天的出库数量
        OutboundVO outboundVO = new OutboundVO()
                .setRepositoryId(productVO.getRepositoryId())
                .setIsDelete(productVO.getIsDelete());
        List<OutboundDTO> outNumList = outboundService.getOutNumByTime(outboundVO);
        Map<String, Integer> outNumMap = outNumList.stream()
                .collect(Collectors.toMap(
                        v -> v.getProductId() + "-" + v.getRepositoryId()
                        , v -> v.getActualNum() == null ? 0 : v.getActualNum()));

        for (ProductDTO productDTO : productDTOList) {
            // 初始化 入库成本：元 （costYuan）  盒装数量（boxNum）
            productDTO.init();

            // 设置前30天销量
            Integer num = outNumMap.get(productDTO.getId() + "-" + productDTO.getRepositoryId());
            if (num == null) {
                continue;
            }
            BigDecimal warnBoxNum = BigDecimal.valueOf(num)
                    .divide(BigDecimal.valueOf(productDTO.getPerBox()), 2, RoundingMode.UP);
            productDTO.setWarnBoxNum(warnBoxNum);
        }

        productDTOList = productDTOList.stream()
                .sorted(ProductComparator::compare)
                .collect(Collectors.toList());
        return Result.success(productDTOList);
    }

    /**
     * 列表导出
     *
     * @param productVO
     * @return
     */
    @Override
    public Result export(ProductVO productVO) {

        List<ProductDTO> productDTOList = getList(productVO).getData();
        List<ProductExport> productExportList = MyBeanUtils.copyList(productDTOList, ProductExport.class);

        FileParams writeParams = new FileParams(FileEnum.PRODUCT_EXPORT, DateUtils.getNowStr(), "");
        int writeNum = POIExcelUtils.write(writeParams.getPathName(), productExportList, writeParams.getClazz());

        return Result.create(writeNum);
    }

    /**
     * 修改一条记录
     *
     * @param productVO
     * @return
     */
    @Override
    public Result updateOne(ProductVO productVO) {
        boolean updateInfo = updateById(MyBeanUtils.copy(productVO, Product.class));
        boolean updateSuccess = stockService.updateByQuery(new StockVO()
                .setRepositoryId(productVO.getRepositoryId())
                .setProductId(productVO.getId())
                .setNum(productVO.getNum()));
        dataInitializer.initProduct();
        return Result.success("商品信息修改：   " + updateInfo + "<br>库存修改：  " + updateSuccess);
    }

    /**
     * 删除一条记录
     *
     * @param productVO
     * @return
     */
    @Override
    public Result deleteOne(ProductVO productVO) {
        return updateOne(productVO);
    }

    /**
     * 新增一条记录
     *
     * @param productVO
     * @return
     */
    @Override
    public Result addOne(ProductVO productVO) {
        boolean save = save(MyBeanUtils.copy(productVO, Product.class));
        dataInitializer.initProduct();
        return Result.create(save);
    }


    /**
     * 根据id获取名称
     *
     * @return
     */
    @Override
    public String getNameById(Integer id) {
        // 获取缓存
        Map<Integer, String> productMap = DataInitializer.getProductMap();
        // 通过数据库获取并写到缓存，再次获取缓存
        if (productMap == null || productMap.isEmpty()) {
            productMap = dataInitializer.initProduct();
        }
        return productMap.get(id);
    }

    /**
     * 根据 sku集合
     * 获取所有 商品的sku，店铺Id，商品信息
     *
     * @return skuList
     */
    @Override
    public List<ProductDTO> getProductListBySkuList(List<String> skuList) {
        if (skuList.isEmpty()) {
            return new ArrayList<>();
        }
        return productMapper.getProductListBySkuList(skuList);
    }

    //============================================私有方法开始============================================
    //============================================私有方法结束============================================
}




